<?php
/* required libraries */
require('./library/strings.php');
require('./library/classes.php');

/* generate the search rsults and display them */
$search = new CABLEsearch();
echo $search->source;

/* classes */
class CABLEsearch
{
	public	$source;
	public	$config;
	public	$db;
	public	$user;

	private $plugins	= array();
	private	$template;
	private	$messages = array();
	private $error = false;
	
	public function __construct()
	{
		$this->error = true;
		$this->config = new CABLEconfig();
		if ($this->config->error === false)
		{
			$this->db = new CABLEdb();
			if ($this->db->Connect($this->config->values['DbServer'],$this->config->values['DbUsername'],$this->config->values['DbPassword'],$this->config->values['DbName']))
			{
				$this->user	= new CABLEuser($this->config,$this->db);
				if ($this->user->error === false)
				{			
					if (($content = $this->BuildSearch()) !== false)
					{
						$this->source = $content;
						$this->error = false;
					}
				}
			}
		}
		
		/* message consolidation */
		if (($this->config->values['ErrorThreshold'] > 0) || ($this->error !== false))
		{
			$this->messages = CABLE_MessageArrayCombine($this->messages,$this->config->messages);
			$this->messages = CABLE_MessageArrayCombine($this->messages,$this->db->messages);
			$this->messages = CABLE_MessageArrayCombine($this->messages,$this->user->messages);
			$this->messages = CABLE_MessageArrayCombine($this->messages,$this->cache->messages);
			$this->messages = CABLE_MessageArrayCombine($this->messages,$this->template->messages);
			
			$this->source = CABLE_MakeMessages($this->messages,$this->config->values['ErrorThreshold']).$this->source;
		}
		
		return null;
	}
	
	private	function BuildSearch()
	{		
		/* load template from db */
		$this->template = new CABLEtemplate($this->config,$this->db,$this->config->values['ThemeName'],'search');
		if ($this->template->error)
			return false;
		
		/* build the entries */
		$entries = array();
		
		/* do some string formatting for mysql */
		$string = str_replace('"','',str_replace('\'','',urldecode($_REQUEST['s'])));
		$string = str_replace('*','%',$string);
		$string = '%'.str_replace('?','_',$string).'%';
		
		/* build the table name on which to execute the query */
		$table = "cable_".$this->config->values['TablePrefix']."_entries";
				
		/* bail if string is too short */
		if (strlen($string) > 5)
		{
			/* determine what field we're supposed to be matching against */
			switch(urldecode($_REQUEST['f']))
			{
				case 'author':
					$query = "SELECT timestamp,author,title,data FROM $table WHERE author LIKE '$string' ORDER BY timestamp DESC LIMIT ".$this->config->values['SearchEntries'];
					break;
				case 'title':
					$query = "SELECT timestamp,author,title,data FROM $table WHERE title LIKE '$string' ORDER BY timestamp DESC LIMIT ".$this->config->values['SearchEntries'];;
					break;
				case 'text':
					$query = "SELECT timestamp,author,title,data FROM $table WHERE text LIKE '$string' ORDER BY timestamp DESC LIMIT ".$this->config->values['SearchEntries'];
					break;
				default:
					$query = "SELECT timestamp,author,title,data FROM $table WHERE data LIKE '$string' ORDER BY timestamp DESC LIMIT ".$this->config->values['SearchEntries'];
					break;
			}

			/* execute query */	
			if (($result = mysql_query($query,$this->db->db_link)) === false)
			{
				$this->messages[0][] = str_replace('<id>',mysql_error($this->db->db_link),CABLE_ERROR_DATABASE_REQUEST);
				return false;
			}
			
			/* load entry data results into array */
			while ($row = mysql_fetch_assoc($result))
			{
				/* extract serialized entry data */
				$data = unserialize($row[data]);
				unset($row[data]);
				foreach($data as $key => $value)
				{
					if (!isset($entry_array[$key]))
					{
						if (is_string($value))
							$entry_array[$key] = rawurldecode($value);
						else
							$entry_array[$key] = $value;
					}
				}
				
				$entries[$row[timestamp]] = array_merge($data,$row);
			}
			
			if ($this->config->values['SearchSort'] != 'descending')
				ksort($entries);
		}

		/* load plugins and run initialization routines */
		$plugin_names = explode(',',$this->config->values['SearchPlugins']);
		foreach($plugin_names as $name)
		{
			$this->plugins[$name] = new CABLEplugin($name,$this->config,$this->db,$this->user);
			$this->plugins[$name]->Connect($this->template,$entries);
			$this->plugins[$name]->Execute('open');
			
			/* retrieve plugin messages */
			$this->messages = CABLE_MessageArrayCombine($this->messages,$this->plugins[$name]->messages);
			unset($this->plugins[$name]->messages);
			
			/* bail if necessary */
			if ($this->plugins[$name]->abort)
				break;
		}
		
		/* drop entries marked for deletion */
		foreach($entries as $timestamp => $entry_data)
			if ($entry_data[delete])
				unset($entries[$timestamp]);
	
		/* iterate through search data */
		$counter = 0;
		foreach($entries as $entry_data)
		{
			$entry_data[counter] = $counter;
			$entry_data[num] = count($entries);
			
			/* run plugin routines */
			foreach($plugin_names as $name)
			{
				$this->plugins[$name]->Connect($this->template,$entry_data);
				$this->plugins[$name]->Execute('');
				
				/* retrieve plugin messages */
				$this->messages = CABLE_MessageArrayCombine($this->messages,$this->plugins[$name]->messages);
				unset($this->plugins[$name]->messages);
				
				/* bail if necessary */
				if ($this->plugins[$name]->abort)
					break;
			}
			
			$counter++;
		}

		/* run plugin closing routines */
		foreach($plugin_names as $name)
		{
			$this->plugins[$name]->Connect($this->template,$entries);
			$this->plugins[$name]->Execute('close');
			
			/* retrieve plugin messages */
			$this->messages = CABLE_MessageArrayCombine($this->messages,$this->plugins[$name]->messages);
			unset($this->plugins[$name]->messages);
			
			/* bail if necessary */
			if ($this->plugins[$name]->abort)
				break;
			
			/* clean up */
			unset($this->plugins[$name]);
		}
		
		return $this->template->Render();
	}
}

?>